iT邦幫忙

2024 iThome 鐵人賽

DAY 12
0
Modern Web

剛入行就一人重新打造公司前端系統?系列 第 12

Day 12 - SOLID 原則在 React 的實踐(二)

  • 分享至 

  • xImage
  •  

接續 SOLID 原則在 React 的實踐(一),今天會繼續寫~

里氏替換原則 Liskov Substitution Principle (LSP)

“Objects of a superclass should be replaceable with objects of its subclasses.“

雖然在原本 LSP 概念中指的是 superclass 的 subclass 可以替換其 superclass 而不會破壞掉功能。像 RacingCarCar 的 subclass,那麼我們應該能夠用 RacingCar 替換 Car 的實例。換句話說,RacingCar 必須滿足 Car 類別所設定的所有預期行為。

在 React 中 LSP 的應用是,當我們替換一個父元件時,子元件應該能夠繼續執行相同的工作。也就是說,如果一個元件使用了另一個元件,那麼即使替換了父元件,應用程式還是能正常運作,不會因為替換了元件而破壞其行為。直接看範例吧:

範例:

假設我們有一個基礎的 <ImageDisplay> 元件,並且我們想要擴展它來支持不同的顯示風格:

// 基本的顯示圖片功能

const ImageDisplay = ({ src, alt }) => {
  return (
    <img src={src} alt={alt} className="w-full h-auto" />
  );
};

接下來, <RoundedImageDisplay> 在基本功能上添加了圓角樣式:

// 顯示圖片加上圓角的樣式,擴展了 <ImageDisplay>

const RoundedImageDisplay = ({ src, alt }) => {
  return (
    <ImageDisplay
      src={src}
      alt={alt}
      className="w-24 h-24 rounded-full object-cover"
    />
  );
};
  • <RoundedImageDisplay> 擴展了 <ImageDisplay>,並且能夠使用 <ImageDisplay> 元件的所有功能,但添加了額外的樣式。

確保符合 LSP - 做替換測試

以下範例可以看到能安全地用 <RoundedImageDisplay> 替換 <ImageDisplay>,而不會改變行為或破壞功能,因此符合 Liskov Substitution Principle (LSP)。

// 在 App 中使用 <ImageDisplay> 顯示圖片:

const App = () => {
  return (
    <div>
      <ImageDisplay src="image.jpg" alt="Description" />
    </div>
  );
};

// 在 App 中能安全地用 <RoundedImageDisplay> 替換 <ImageDisplay>
const App = () => {
  return (
    <div>
      <RoundedImageDisplay src="image.jpg" alt="Description" />
    </div>
  );
};

介面隔離原則 Interface Segregation Principle (ISP)

“No code should be forced to depend on methods it does not use.“

在物件導向中,ISP 指的是不應該強迫一個類別(class)實作它不使用的介面(interface)和方法(method)。

那在 React 中,可以是「元件不應依賴它們不使用的 props」,或是「React hooks 可以幫助你將不同的行為邏輯拆分」

範例 - 元件不應依賴它們不使用的 props:

假設一個 <ListItem> 元件只需要顯示用戶的名字和電子郵件:

// ❌ 錯誤範例:違反 ISP,<ListItem> 只需要 image, title, description

const ListItem = ({ item }) => {
  return (
    <View>
      <Image source={{ uri: item.image }} />
      <Text>{item.title}</Text>
      <Text>{item.description}</Text>
    </View>
  );
};
  • 範例中 <ListItem> 元件接收一個 item prop,但這個 item prop 可能包含許多其他資料。
  • 然而 <ListItem> 元件只需要 item 中的 imagetitledescription 三個字段,這樣的設計可能會導致不必要的依賴

為了遵守 Interface Segregation Principle(ISP),我們可以將 <ListItem> 元件的 props 精簡為僅包含它實際需要的字段:

// ⭕️ 正確做法:傳入 <ListItem> 需要的 image, title, description

const ListItem = ({ image, title, description }) => {
  return (
    <View>
      <Image source={{ uri: image }} />
      <Text>{title}</Text>
      <Text>{description}</Text>
    </View>
  );
}
  • 為何這樣做更符合 ISP?
    1. 避免不必要的依賴:避免從 item prop 中獲取不必要的資料,從而減少了不必要的依賴和潛在的錯誤。
    2. 簡化測試與易維護:簡化的元件 props 使得測試和調試過程變得更容易。測試時,只需要關注元件的核心功能,而不需要處理額外的、未使用的 props。

參考資料


上一篇
Day 11 - SOLID 原則在 React 的實踐(一)
下一篇
Day 13 - React 最佳實踐專案推薦!
系列文
剛入行就一人重新打造公司前端系統?27
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言